package com.xh.web.service.impl;


import com.xh.web.constant.Constants;
import com.xh.web.constant.DbModuleConstants;
import com.xh.web.domain.*;
import com.xh.web.domain.vo.ColumnVo;
import com.xh.web.domain.vo.ExportColumnVo;
import com.xh.web.domain.vo.TableVo;
import com.xh.web.mapper.*;
import com.xh.web.service.IDColumnService;
import com.xh.web.util.DateUtils;
import com.xh.web.util.StringUtils;
import com.xh.web.util.velocity.VelocityInitializer;
import com.xh.web.util.velocity.VelocityUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.StringWriter;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 字段Service业务层处理
 *
 * @author fulan
 * @date 2020-09-04
 */
@Service
@Transactional
public class DColumnServiceImpl implements IDColumnService {
    @Autowired(required = false)
    private DColumnMapper dColumnMapper;
    @Autowired(required = false)
    private DTableMapper dTableMapper;
    @Autowired(required = false)
    private DProjectHisMapper dProjectHisMapper;
    @Autowired(required = false)
    private DProjectMapper dProjectMapper;
    @Autowired(required = false)
    private DTableIndexMapper dTableIndexMapper;


    /**
     * 根据id进行查询
     *
     * @param
     * @return 字段集合
     */
    public DColumn selectColumnById(String id) {
        return dColumnMapper.selectColumnById(id);
    }


    /**
     * 查询字段列表
     *
     * @param dColumn 字段
     * @return 字段
     */
    @Override
    public List<DColumn> selectDColumnList(DColumn dColumn) {
        if(StringUtils.isNotNull(dColumn.getTemplateId())){
            return dColumnMapper.selectByTemplateId(dColumn.getTemplateId());
        }
        return dColumnMapper.selectDColumnList(dColumn);
    }

    /**
     * 新增字段
     *
     * @param dColumn 字段
     * @return 结果
     */
    @Override
    public int insertDColumn(DColumn dColumn) {
        try {

            DTable dTable = dTableMapper.selectDTableById(dColumn.getTableId());
            if (dTable == null) {
                return 0;
            }
            dTable.setColumnNum(dColumnMapper.selectColumnCount(dTable.getId()) + 1);
            dColumn.setProjectId(dTable.getProjectId());
            //SysUser user = SecurityUtils.getLoginUser().getUser();
            dColumn.setCreateBy("admin");
            dColumn.setCreateDate(new Date());
            dColumn.setUpdateBy("admin");
            dColumn.setUpdateDate(new Date());
            dColumn.setDelFlag("0");
            dColumn.setdSort(new Long(0));

            if (StringUtils.isNotEmpty(dColumn.getIndexType())&&StringUtils.isNotEmpty(dColumn.getIndexColumn())) {
                DTableIndex dTableIndex = new DTableIndex();
                dTableIndex.setProjectId(dTable.getProjectId());
                StringBuffer strColumns = new StringBuffer();
                String idxName = dTable.getTableCode().replace("_", "");

                String[] indexColumns = dColumn.getIndexColumn().split(",");
                for (String indexColumn : indexColumns) {
                    strColumns.append(indexColumn.replace("_", "").trim());
                }
              String tableIndexName="idx_"+idxName+"_"+strColumns;

                if (tableIndexName.length()>30){
                    tableIndexName= tableIndexName.substring(0,30);
                }
                dTableIndex.setIndexName(tableIndexName);
                dTableIndex.setIndexType(dColumn.getIndexType());
                dTableIndex.setIndexColumn(dColumn.getIndexColumn());
                dTableIndex.setIndexCtype(dColumn.getIndexCtype());
                dTableIndex.setTableCode(dTable.getTableCode());
                dTableIndex.setTableName(dTable.getTableName());
                dTableIndex.setCreateBy("admin");
                dTableIndex.setCreateDate(new Date());
                dTableIndex.setUpdateBy("admin");
                dTableIndex.setUpdateDate(new Date());
                dTableIndex.setDelFlag("0");
                dTableIndexMapper.insertDTableIndex(dTableIndex);

                dColumn.setIndexName(dTableIndex.getIndexName());
                dColumn.setIndexId(dTableIndex.getId());
            }
            //dTableMapper.updateDTable(dTable);
            //保存历史
            DProjectHis dProjectHis = new DProjectHis();
            dProjectHis.setProjectId(dTable.getProjectId());
            dProjectHis.setOperationType("3");
            dProjectHis.setOperationDesc("新增字段：" + dColumn.getColumnCode());
            dProjectHis.setCreateBy("admin");
            dProjectHis.setCreateName("admin");
            dProjectHis.setCreateDate(new Date());
            dProjectHis.setUpdateBy("admin");
            dProjectHis.setUpdateDate(new Date());
            dProjectHis.setDelFlag("0");
            dProjectHis.setTableCode(dTable.getTableCode());
            dProjectHis.setTableName(dTable.getTableName());
            dProjectHisMapper.insertDProjectHis(dProjectHis);

            dTable.setUpdateName("admin");
            dTable.setUpdateDate(new Date());
            dTable.setUpdateBy("admin");
            dTableMapper.updateDTable(dTable);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dColumnMapper.insertDColumn(dColumn);
    }

    @Transactional
    public int insertChoiceDColumn(String [] ids,String tableId){
        //SysUser user = SecurityUtils.getLoginUser().getUser();
        DTable table = dTableMapper.selectDTableById(tableId);
        for (String id: ids) {
            DColumn dColumn = dColumnMapper.selectColumnById(id);
            dColumn.setId(null);
            dColumn.setTemplateId(null);
            dColumn.setTableId(table.getId());
            dColumn.setTableCode(table.getTableCode());
            dColumn.setCreateDate(DateUtils.getNowDate());
            dColumn.setCreateBy("admin");
            dColumn.setUpdateDate(DateUtils.getNowDate());
            dColumn.setUpdateBy("admin");
            dColumn.setIndexColumn(null);
            dColumn.setIndexCtype(null);
            dColumn.setIndexId(null);
            dColumn.setIndexName(null);
            dColumn.setIndexType(null);
            dColumnMapper.insertDColumn(dColumn);
        }
        table.setColumnNum(table.getColumnNum()+ids.length);
        dTableMapper.updateDTable(table);
        return 1;
    }

    /**
     * 修改字段
     *
     * @param dColumn 字段
     * @return 结果
     */
    @Override
    public int updateDColumn(DColumn dColumn) {
        dColumn.setUpdateDate(new Date());
        //SysUser user1 = SecurityUtils.getLoginUser().getUser();
        DColumn dColumn1 = dColumnMapper.selectColumnById(dColumn.getId());
        DTable table = dTableMapper.selectDTableById(dColumn.getTableId());

        //只更新排序
        if(StringUtils.isNotNull(dColumn.getId())&&StringUtils.isNull(dColumn.getColumnCode())){
            return dColumnMapper.updateDColumn(dColumn);
        }

        if (StringUtils.isNotEmpty(dColumn.getIndexType())&&StringUtils.isNotEmpty(dColumn.getIndexColumn())){
            if (dColumn1.getIndexId() == null) {

                DTableIndex dTableIndex = new DTableIndex();
                dTableIndex.setProjectId(dColumn.getProjectId());
                StringBuffer strColumns = new StringBuffer();
                String idxName = table.getTableCode().replace("_", "");

                String[] indexColumns = dColumn.getIndexColumn().split(",");
                for (String indexColumn : indexColumns) {
                    strColumns.append(indexColumn.replace("_", "").trim());
                }
               String tableIndexName="idx_"+idxName+"_"+strColumns;
                if (tableIndexName.length()>30){
                    tableIndexName=tableIndexName.substring(0,31);
                }
                dTableIndex.setIndexName(tableIndexName);
                dTableIndex.setIndexType(dColumn.getIndexType());
                dTableIndex.setIndexCtype(dColumn.getIndexCtype());
                dTableIndex.setIndexColumn(dColumn.getIndexColumn());
                dTableIndex.setTableCode(table.getTableCode());
                dTableIndex.setTableName(table.getTableName());
                dTableIndex.setCreateBy("admin");
                dTableIndex.setCreateDate(new Date());
                dTableIndex.setUpdateBy("admin");
                dTableIndex.setUpdateDate(new Date());
                dTableIndex.setDelFlag("0");
                dTableIndexMapper.insertDTableIndex(dTableIndex);
                dColumn.setIndexId(dTableIndex.getId());
                dColumn.setIndexName(dTableIndex.getIndexName());
            } else {
                DTableIndex dTableIndex = new DTableIndex();
                dTableIndex.setId(dColumn1.getIndexId());
                dTableIndex.setIndexColumn(dColumn.getIndexColumn());
                dTableIndex.setIndexType(dColumn.getIndexType());
                dTableIndex.setIndexCtype(dColumn.getIndexCtype());
                dTableIndex.setIndexCtype(dColumn.getIndexCtype());
                dTableIndexMapper.updateDTableIndex(dTableIndex);
            }
        }
        //保存历史
        boolean isUpdate = false;
        StringBuffer sb = new StringBuffer();
        DColumn oldColumn = dColumnMapper.selectColumnById(dColumn.getId());
        if (!oldColumn.getColumnCode().equals(dColumn.getColumnCode())) {
            isUpdate = true;
            sb.append("字段从：" + oldColumn.getColumnCode() + "改为：" + dColumn.getColumnCode());
        }
        if (!oldColumn.getDataType().equals(dColumn.getDataType())) {
            isUpdate = true;
            String br = "";
            if (sb.length() > 0) {
                br = "<br/>";
            }
            sb.append(br + "字段：" + dColumn.getColumnCode() + "的数据类型从：" + oldColumn.getDataType() + "改为：" + dColumn.getDataType());
        }
        if (oldColumn.getdLength() != null && dColumn.getdLength() != null && !oldColumn.getdLength().equals(dColumn.getdLength())) {
            isUpdate = true;
            String br = "";
            if (sb.length() > 0) {
                br = "<br/>";
            }
            sb.append(br + "字段：" + dColumn.getColumnCode() + "的长度从：" + oldColumn.getdLength() + "改为：" + dColumn.getdLength());
        }
        if (isUpdate) {
            DTable dTable = dTableMapper.selectDTableById(dColumn.getTableId());
            //SysUser user = SecurityUtils.getLoginUser().getUser();
            DProjectHis dProjectHis = new DProjectHis();
            dProjectHis.setProjectId(dTable.getProjectId());
            dProjectHis.setOperationType("3");
            dProjectHis.setOperationDesc(sb.toString());
            dProjectHis.setCreateBy("admin");
            dProjectHis.setCreateName("admin");
            dProjectHis.setCreateDate(new Date());
            dProjectHis.setUpdateBy("admin");
            dProjectHis.setUpdateDate(new Date());
            dProjectHis.setDelFlag("0");
            dProjectHis.setTableCode(dTable.getTableCode());
            dProjectHis.setTableName(dTable.getTableName());
            dProjectHisMapper.insertDProjectHis(dProjectHis);
        }
        table.setUpdateName("admin");
        table.setUpdateDate(new Date());
        table.setUpdateBy("admin");
        dTableMapper.updateDTable(table);

        return dColumnMapper.updateDColumn(dColumn);
    }

    /**
     * 批量删除字段
     *
     * @param ids 需要删除的字段ID
     * @return 结果
     */
    @Override
    public int deleteDColumnByIds(String[] ids) {
        return dColumnMapper.deleteDColumnByIds(ids);
    }

    /**
     * 删除字段信息
     *
     * @param id 字段ID
     * @return 结果
     */
    @Override
    public int deleteDColumnById(String id) {
        DColumn dColumn = dColumnMapper.selectColumnById(id);

        if(StringUtils.isNotNull(dColumn.getTemplateId())){
            return dColumnMapper.deleteDColumnById(id);
        }
        DTable dTable = dTableMapper.selectDTableById(dColumn.getTableId());
        if (dTable == null) {
            return 0;
        }
        dTable.setColumnNum(dColumnMapper.selectColumnCount(dTable.getId())-1);
        //dTableMapper.updateDTable(dTable);
        //保存历史
        //SysUser user = SecurityUtils.getLoginUser().getUser();
        DProjectHis dProjectHis = new DProjectHis();
        dProjectHis.setProjectId(dTable.getProjectId());
        dProjectHis.setOperationType("3");
        dProjectHis.setOperationDesc("删除字段：" + dColumn.getColumnCode());
        dProjectHis.setCreateBy("admin");
        dProjectHis.setCreateName("admin");
        dProjectHis.setCreateDate(new Date());
        dProjectHis.setUpdateBy("admin");
        dProjectHis.setUpdateDate(new Date());
        dProjectHis.setDelFlag("0");
        dProjectHis.setTableCode(dTable.getTableCode());
        dProjectHis.setTableName(dTable.getTableName());
        dProjectHisMapper.insertDProjectHis(dProjectHis);

        dTable.setUpdateName("admin");
        dTable.setUpdateDate(new Date());
        dTable.setUpdateBy("admin");
        dTableMapper.updateDTable(dTable);

        return dColumnMapper.deleteDColumnById(id);
    }


    /**
     * 根据字段code查询
     *
     * @param
     * @return 结果
     */
    public DColumn selectColumnByCode(String columnCode, String tableId) {
        return dColumnMapper.selectColumnByCode(columnCode, tableId);
    }


    @Override
    public List<TableVo> selectTables(ColumnVo columnVo) {
        return dColumnMapper.selectTables(columnVo);
    }

    @Override
    public List<ExportColumnVo> selectExportColumn(String[] tableIds) {
        return dColumnMapper.selectExportColumn(tableIds);
    }

    @Override
    public int insertDColumnListOfficial(List<DColumn> columnList) {
        return dColumnMapper.insertDColumnListOfficial(columnList);
    }

    @Override
    public String[] selectColumnIdList(String[] tableIds) {
        return dColumnMapper.selectColumnIdList(tableIds);
    }


    /**
     * 预览代码
     *
     * @param
     * @return 预览数据列表
     */
    @Override
    public Map<String, String> previewCode(String id) {
        Map<String, String> dataMap = new LinkedHashMap<>();
        // 查询表信息
        DColumn dColumn = dColumnMapper.selectColumnById(id);
        DTable dTable = dTableMapper.selectDTableById(dColumn.getTableId());
        DProject dProject = dProjectMapper.selectDProjectById(dColumn.getProjectId());

        VelocityInitializer.initVelocity();
        VelocityContext context = new VelocityContext();
        context.put("tableCode", dTable.getTableCode());
        context.put("dColumn", dColumn);
        //字符默认值需要加单引号
        if(StringUtils.isNotEmpty(dColumn.getDefaultValue())&& DbModuleConstants.dataType.contains(dColumn.getDataType().toLowerCase())){
            context.put("defaultValue", "'"+dColumn.getDefaultValue()+"'");
        }else {
            context.put("defaultValue", dColumn.getDefaultValue());
        }
        // 获取模板列表
        List<String> templates = VelocityUtils.getTemplateList("column_"+dProject.getDbType());
        for (String template : templates) {
            // 渲染模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
            tpl.merge(context, sw);
            dataMap.put(template, sw.toString());
        }
        return dataMap;
    }

    //根据表id查询column
    public List<DColumn> selectColumnByTableId(String tableId) {
        return dColumnMapper.selectByTableId(tableId);
    }

    //根据表projectId查询column
    public List<ColumnVo> selectDProjectById(ColumnVo columnVo){return dColumnMapper.selectDProjectById(columnVo);}

    public int joinTemplate(DColumn dColumn){
        //SysUser user = SecurityUtils.getLoginUser().getUser();
        DColumn tcolumn=dColumnMapper.selectColumnById(dColumn.getId());
        tcolumn.setId(null);
        tcolumn.setTableId(null);
        tcolumn.setTemplateId(dColumn.getTemplateId());
        tcolumn.setCreateBy("admin");
        tcolumn.setCreateDate(DateUtils.getNowDate());
        tcolumn.setUpdateBy("admin");
        tcolumn.setUpdateDate(DateUtils.getNowDate());
        return dColumnMapper.insertDColumn(tcolumn);
    }


}
